// Copyright 2024 Xiguan Inc
// Author: xiguan
// Email: xiguan.teng@qq.com
// Created on 2024/8/7
// This is ...
//
#include <wc.h>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

int main(int argc, char *argv[]) {
  std::stringstream ss;

  if (argc < 2) {
    ss << "Usage: <" << argv[0] << "> <inputfile>s.";
    std::cout << ss.str() << std::endl;
  }

  VecMapRet intermediate;

  for (auto idx = 1; idx < argc; ++idx) {
    //    std::cout << "Now deal with " << argv[idx] << std::endl;
    std::string   filename = argv[idx];
    std::ifstream file(filename);
    if (!file.is_open()) {
      ss << "file " << filename << " opened filed. " << __func__ << ":"
         << __LINE__ << " in file " << __FILE__ << std::endl;
      std::cerr << ss.str() << std::endl;
      ss.clear();
      continue;
    }

    auto              content = file.rdbuf();
    std::stringstream ss_content;
    ss_content << content;

    auto kva = lab1_map(filename, ss_content.str());
    intermediate.insert(intermediate.end(), kva.begin(), kva.end());

    ss.clear();
    file.close();
    ss_content.clear();
  }
  std::cout << "size: " << intermediate.size() << std::endl;
  std::sort(intermediate.begin(), intermediate.end(),
            [](std::pair<std::string, int> a, std::pair<std::string, int> b) {
              return a.first < b.first;
            });

  std::ofstream outfile("./mr_out_0");
  if (!outfile.is_open()) {
    ss << "output file"
       << " opened filed. " << __func__ << ":" << __LINE__ << " in file "
       << __FILE__ << std::endl;
    std::cerr << ss.str() << std::endl;
    ss.clear();
  }

  int idx = 0;
  int len = intermediate.size();
  while (idx < len) {
    int jdx = idx + 1;
    while (jdx < len && intermediate[idx].first == intermediate[jdx].first) {
      jdx++;
    }

    std::vector<decltype(intermediate[idx].second)> values;
    for (int t = idx; t < jdx; ++t) {
      values.push_back(intermediate[t].second);
    }

    auto output = lab1_reduce(intermediate[idx].first, values);
    outfile << intermediate[idx].first << " " << output << std::endl;
    idx = jdx;
  }

  outfile.close();

  return 0;
}